From bd643e0e1afff720db2f2f512818f0b2633a6213 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Thu, 6 Nov 2014 17:17:45 -0500 Subject: [PATCH] x11: Keep track of the exact size in X pixels of windows Keep track of the exact size of X windows in underlying pixels; we generally use the scaled size instead, but to properly handle the GL viewport for windows that aren't a multiple of window_scale, we need to know the real size. https://bugzilla.gnome.org/show_bug.cgi?id=739750 --- gdk/x11/gdkdisplay-x11.c | 8 ++++-- gdk/x11/gdkgeometry-x11.c | 2 ++ gdk/x11/gdkwindow-x11.c | 51 ++++++++++++++++++++++++++++----------- gdk/x11/gdkwindow-x11.h | 8 ++++++ 4 files changed, 53 insertions(+), 16 deletions(-) diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index d5cf7d666f..d6543c1e38 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -767,11 +767,13 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator, : "")); if (window && GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT) { + window_impl->unscaled_width = xevent->xconfigure.width; + window_impl->unscaled_height = xevent->xconfigure.height; window->width = (xevent->xconfigure.width + window_impl->window_scale - 1) / window_impl->window_scale; window->height = (xevent->xconfigure.height + window_impl->window_scale - 1) / window_impl->window_scale; _gdk_window_update_size (window); - _gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl)); + _gdk_x11_window_update_size (window_impl); _gdk_x11_screen_size_changed (screen, xevent); } @@ -826,11 +828,13 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator, { window->x = event->configure.x; window->y = event->configure.y; + window_impl->unscaled_width = xevent->xconfigure.width; + window_impl->unscaled_height = xevent->xconfigure.height; window->width = event->configure.width; window->height = event->configure.height; _gdk_window_update_size (window); - _gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl)); + _gdk_x11_window_update_size (window_impl); if (window->resize_count >= 1) { diff --git a/gdk/x11/gdkgeometry-x11.c b/gdk/x11/gdkgeometry-x11.c index cfcbec891a..5fac8fd766 100644 --- a/gdk/x11/gdkgeometry-x11.c +++ b/gdk/x11/gdkgeometry-x11.c @@ -62,6 +62,8 @@ _gdk_x11_window_move_resize_child (GdkWindow *window, window->x = x; window->y = y; + impl->unscaled_width = width * impl->window_scale; + impl->unscaled_height = height * impl->window_scale; window->width = width; window->height = height; diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index ec4eead362..c4b90af74b 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -194,8 +194,7 @@ _gdk_x11_window_update_size (GdkWindowImplX11 *impl) if (impl->cairo_surface) { cairo_xlib_surface_set_size (impl->cairo_surface, - gdk_window_get_width (impl->wrapper) * impl->window_scale, - gdk_window_get_height (impl->wrapper) * impl->window_scale); + impl->unscaled_width, impl->unscaled_height); } } @@ -734,6 +733,8 @@ _gdk_x11_screen_init_root_window (GdkScreen *screen) window->y = 0; window->abs_x = 0; window->abs_y = 0; + impl->unscaled_width = WidthOfScreen (x11_screen->xscreen); + impl->unscaled_height = HeightOfScreen (x11_screen->xscreen); window->width = WidthOfScreen (x11_screen->xscreen) / impl->window_scale; window->height = HeightOfScreen (x11_screen->xscreen) / impl->window_scale; window->viewable = TRUE; @@ -1080,6 +1081,9 @@ _gdk_x11_display_create_window_impl (GdkDisplay *display, window->height = 32767 / impl->window_scale; } + impl->unscaled_width = window->width * impl->window_scale; + impl->unscaled_height = window->height * impl->window_scale; + impl->xid = XCreateWindow (xdisplay, xparent, (window->x + window->parent->abs_x) * impl->window_scale, (window->y + window->parent->abs_y) * impl->window_scale, @@ -1229,6 +1233,8 @@ gdk_x11_window_foreign_new_for_display (GdkDisplay *display, win->x = attrs.x / impl->window_scale; win->y = attrs.y / impl->window_scale; + impl->unscaled_width = attrs.width; + impl->unscaled_height = attrs.height; win->width = attrs.width / impl->window_scale; win->height = attrs.height / impl->window_scale; win->window_type = GDK_WINDOW_FOREIGN; @@ -1789,13 +1795,15 @@ window_x11_resize (GdkWindow *window, if (impl->override_redirect) { + impl->unscaled_width = width * impl->window_scale; + impl->unscaled_height = height * impl->window_scale; window->width = width; window->height = height; _gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl)); } else { - if (width != window->width || height != window->height) + if (width * impl->window_scale != impl->unscaled_width || height * impl->window_scale != impl->unscaled_height) window->resize_count += 1; } } @@ -1835,6 +1843,8 @@ window_x11_move_resize (GdkWindow *window, window->x = x; window->y = y; + impl->unscaled_width = width * impl->window_scale; + impl->unscaled_height = height * impl->window_scale; window->width = width; window->height = height; @@ -1842,7 +1852,7 @@ window_x11_move_resize (GdkWindow *window, } else { - if (width != window->width || height != window->height) + if (width * impl->window_scale != impl->unscaled_width || height * impl->window_scale != impl->unscaled_height) window->resize_count += 1; } } @@ -1922,17 +1932,30 @@ _gdk_x11_window_set_window_scale (GdkWindow *window, (window->x + window->parent->abs_x) * impl->window_scale, (window->y + window->parent->abs_y) * impl->window_scale); else if (WINDOW_IS_TOPLEVEL(window)) - XResizeWindow (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - window->width * impl->window_scale, - window->height * impl->window_scale); + { + if (impl->override_redirect) + { + impl->unscaled_width = window->width * impl->window_scale; + impl->unscaled_height = window->height * impl->window_scale; + } + + XResizeWindow (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + window->width * impl->window_scale, + window->height * impl->window_scale); + } else - XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - (window->x + window->parent->abs_x) * impl->window_scale, - (window->y + window->parent->abs_y) * impl->window_scale, - window->width * impl->window_scale, - window->height * impl->window_scale); + { + impl->unscaled_width = window->width * impl->window_scale; + impl->unscaled_height = window->height * impl->window_scale; + + XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + (window->x + window->parent->abs_x) * impl->window_scale, + (window->y + window->parent->abs_y) * impl->window_scale, + window->width * impl->window_scale, + window->height * impl->window_scale); + } gdk_window_invalidate_rect (window, NULL, TRUE); diff --git a/gdk/x11/gdkwindow-x11.h b/gdk/x11/gdkwindow-x11.h index d66e8740f7..2bc2417d8b 100644 --- a/gdk/x11/gdkwindow-x11.h +++ b/gdk/x11/gdkwindow-x11.h @@ -76,6 +76,14 @@ struct _GdkWindowImplX11 gint window_scale; + /* Width and height not divided by window_scale - this matters in the + * corner-case where the window manager assigns us a size that isn't + * a multiple of window_scale - for example for a maximized window + * with an odd-sized title-bar. + */ + gint unscaled_width; + gint unscaled_height; + cairo_surface_t *cairo_surface; #if defined (HAVE_XCOMPOSITE) && defined(HAVE_XDAMAGE) && defined (HAVE_XFIXES) -- 2.30.2